﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Text.RegularExpressions;

namespace WZ.Common
{
    /// <summary>
    /// 分页辅助类
    /// </summary>
    /// <typeparam name="T">类型</typeparam>
    public class PageSource
    {
        #region 私有属性
        private int startPage;
        private int endPage;
        private int previousPageCount = 2;
        private int AfterPageCount = 2;
        private bool showPrevious = true;
        private bool showNext = true;
        private string queryParam;
        #endregion

        #region 公开属性

        private int resultCount;
        /// <summary>
        /// 总记录数
        /// </summary>
        public int ResultCount
        {
            get { return resultCount; }
            set { resultCount = value; }
        }

        private int pageSize;
        /// <summary>
        /// 每页条数
        /// </summary>
        public int PageSize
        {
            get { return pageSize; }
            set { pageSize = value; }
        }

        private int customPage;
        /// <summary>
        /// 当前页
        /// </summary>
        public int CustomPage
        {
            get { return customPage; }
            set { customPage = value; }
        }
        /// <summary>
        /// 总页数
        /// </summary>
        public int PageCount 
        {
            get
            {
                int temp=(resultCount % pageSize) == 0 ? ((resultCount / pageSize)) : (resultCount / pageSize) + 1;
                return temp == 0 ? 1 : temp;
            }
        }
        /// <summary>
        /// 是否首页
        /// </summary>
        public bool IsFirst 
        {
            get
            {
                if (customPage == 1)
                    return true;
                return false;
            }
        }
        /// <summary>
        /// 是否尾页
        /// </summary>
        public bool IsLast
        {
            get
            {
                if (customPage == PageCount)
                    return true;
                return false;
            }
        }
        /// <summary>
        /// 分页导航条
        /// </summary>
        public string PageBar
        {
            get
            {
                return GetPageBar();
            }
        }
        #endregion

        #region 构造方法
        /// <summary>
        /// 分页类构造方法
        /// </summary>
        public PageSource()
        {

        }
        /// <summary>
        /// 根据条件构造分页类
        /// </summary>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">每页条数</param>
        public PageSource(int pageIndex, int pageSize)
        {
            this.customPage = pageIndex;
            this.pageSize = pageSize;
        }
        /// <summary>
        /// 根据条件构造分页类(直接接受Request参数)
        /// </summary>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">每页条数</param>
        public PageSource(string query, int pageSize)
        {
            int _pageIndex = 1;
            if (!int.TryParse(HttpContext.Current.Request[query], out _pageIndex))
            {
                _pageIndex = 1;
            }
            this.queryParam = query;
            this.customPage = _pageIndex;
            this.pageSize = pageSize;
        }
        #endregion

        #region 处理分页导航条
        private string GetPageBar()
        {
            StringBuilder sb = new StringBuilder("<div id=\"Pager\">");
            SetStartPage();
            SetEndPage();
            if (customPage != 1 && showPrevious)			 // 如果需要显示前一页、第一页链接
            {
                sb.Append(string.Format("<a href=\"{0}\">首页</a>", GetPageUrl(1)));
                sb.Append(string.Format("<a href=\"{0}\">上一页</a>", GetPageUrl(customPage - 1)));
            }
            // 循环打印链接
            for (int i = startPage; i <= endPage; i++)
            {


                if (i == customPage)
                {
                    sb.Append(string.Format("<a class=\"CurrentPage\" href=\"#\">{0}</a>", i));
                }
                else
                {
                    sb.Append(string.Format("<a href=\"{0}\">{1}</a>", GetPageUrl(i),i));
                }

            }
            if (customPage != PageCount && showNext)	// 如果需要显示 下一页、最末页 链接
            {
                sb.Append(string.Format("<a href=\"{0}\">下一页</a>", GetPageUrl(customPage + 1)));
                sb.Append(string.Format("<a href=\"{0}\">尾页</a>", GetPageUrl(PageCount)));
            }
            sb.Append(string.Format("<span>{0}/{1}页 &nbsp;&nbsp;{2}条</span></div>",customPage,PageCount,resultCount));
            return sb.ToString();
        }
        // 根据当前页，当前页之前可以显示的页数，算得从第几页开始进行显示
        private void SetStartPage()
        {
            // 如果当前页小于它前面所可以显示的条目数，
            // 那么显示第一页就是实际的第一页
            if (customPage <= previousPageCount)
            {
                startPage = 1;
            }
            else
            // 这种情况下 currentPage 前面总是能显示完，
            // 要根据后面的长短确定是不是前面应该多显示
            {
                if (customPage > previousPageCount + 1)
                    showPrevious = true;

                int linkLength = (PageCount - customPage + 1) + previousPageCount;

                int startPage = customPage - previousPageCount;

                while (linkLength < previousPageCount + AfterPageCount + 1 && startPage > 1)
                {
                    linkLength++;
                    startPage--;
                }

                this.startPage = startPage;
            }
        }

        // 根据CurrentPage、总页数、当前页之后长度 算得显示的最末页是 第几页
        private void SetEndPage()
        {
            // 如果当前页加上它之后可以显示的页数 大于 总页数，
            // 那么显示的最末页就是实际的最末页
            if (customPage + AfterPageCount >= PageCount)
            {
                endPage = PageCount;
            }
            else
            {

                // 这种情况下 currentPage后面的总是可以显示完，
                // 要根据前面的长短确定是不是后面应该多显示

                int linkLength = (customPage - startPage + 1) + AfterPageCount;

                int endPage = customPage + AfterPageCount;

                while (linkLength < previousPageCount + AfterPageCount + 1 && endPage < PageCount)
                {
                    linkLength++;
                    endPage++;
                }

                if (endPage < PageCount)
                    showNext = true;

                this.endPage = endPage;
            }
        }
        public string GetPageUrl(int pageIndex)
        {
            string pageUrl = HttpContext.Current.Request.RawUrl;

            string pattern = @"(?<=[?&]" + queryParam + @"=)(\d+)\b";
            Regex reg = new Regex(pattern, RegexOptions.IgnoreCase);

            // 如果找到匹配，也就是URL中含有类似 ?page=3 或者 &page=4 这样的字符串
            // 则对后面的数值进行替换
            if (reg.IsMatch(pageUrl))
            {
                pageUrl = reg.Replace(pageUrl, pageIndex.ToString());
            }
            else
            {
                string queryString = HttpContext.Current.Request.Url.Query;

                if (string.IsNullOrEmpty(queryString))
                    pageUrl += "?" + queryParam + "=" + pageIndex.ToString();
                else
                    pageUrl += "&" + queryParam + "=" + pageIndex.ToString();
            }

            return pageUrl;
        }
        #endregion
    }
}
